package com.probiz.estoresa.report.web.action;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;

import com.probiz.estore.common.util.DateUtil;
import com.probiz.estore.core.controller.BaseController;
import com.probiz.estore.core.view.MessageContext;
import com.probiz.estore.report.service.ReportDataEngine;

import edu.emory.mathcs.backport.java.util.Collections;

/**
 * 报表模块Controller，所有报表经过此类
 *
 */
public class ReportDataController extends BaseController {
	
	ReportDataEngine reportDataEngine = null;
	Locale locale = null;
	public void setReportDataEngine(ReportDataEngine reportDataEngine) {
		this.reportDataEngine = reportDataEngine;
	}


	public ModelAndView defaultAction(HttpServletRequest request,
			HttpServletResponse response) {
		String reportName = request.getParameter("reportName");
		
		
		
		if("salesAmountByMonth".equals(reportName)){
			return viewSalesAmountByMonth(request, response);
		}else if ("salesAmountByYear".equals(reportName)){
			return viewSalesAmountByYear(request, response);
		}else if("orderCountTrendByMonth".equals(reportName)){
			return viewOrderCountTrendByMonth(request, response);
		}else if("orderCountTrendByYear".equals(reportName)){
			return viewOrderCountTrendByYear(request, response);
		}else if("customerRegTrendByMonth".equals(reportName)){
			return viewCustomerRegTrendByMonth(request, response);
		}else if("customerRegTrendByYear".equals(reportName)){
			return viewCustomerRegTrendByYear(request, response);
		}else if("dashboaderReport".equals(reportName)){
			return this.viewOrderAndCustomerTrendRecently(request, response);
		}
		
		return null;
	}
	
	
	
	private ModelAndView viewCustomerRegTrendByMonth (HttpServletRequest request, HttpServletResponse response){
		locale = request.getLocale();
		MessageContext messageContext = new MessageContext();
		request.setAttribute("caption", getMessage("report.monthCustomerReg.trend"));
		request.setAttribute("xAxisName",getMessage("report.date"));
		//request.setAttribute("yAxisName", "销售量\n（笔）");
		
		String year = request.getParameter("year");
		String month = request.getParameter("month");
		
		java.util.Calendar calendar =  java.util.Calendar.getInstance();
	    year = year==null?String.valueOf(calendar.get(Calendar.YEAR)):year;
	    month = month==null?String.valueOf(calendar.get(Calendar.MONTH)+1):month;
	    String enMonth = null;
		calendar.set(Calendar.YEAR, Integer.valueOf(year));
		calendar.set(Calendar.MONTH, Integer.valueOf(month)-1);
		int dateOfMonth = calendar.getActualMaximum(Calendar.DATE);
		
		//------------------start:英版月份----------------------
	    if(locale.getLanguage().equals("en")){
	    	switch (Integer.valueOf(month)){
	    	case 1:enMonth = "January";break;
	    	case 2:enMonth = "February";break;
	    	case 3:enMonth = "March";break;
	    	case 4:enMonth = "April";break;
	    	case 5:enMonth = "May";break;
	    	case 6:enMonth = "June";break;
	    	case 7:enMonth = "July";break;
	    	case 8:enMonth = "Aguest";break;
	    	case 9:enMonth = "September";break;
	    	case 10:enMonth = "October";break;
	    	case 11:enMonth = "November";break;
	    	case 12:enMonth = "December";break;
	    	default :enMonth ="January" ;break;
	    	}
	    }
		if(locale.getLanguage().equals("en")){
			StringBuilder subcaption = new StringBuilder("(").append(enMonth).append("-").append(year).append(getMessage("report.date.year")+")");
			request.setAttribute("subcaption", subcaption);
		}else{
			StringBuilder subcaption = new StringBuilder("(").append(month).append(getMessage("report.month.to")).append(year).append(getMessage("report.date.year")+")");
			request.setAttribute("subcaption", subcaption);
		}
	
		//------------------end:英版月份----------------------
		
		List<String> nameList = new ArrayList<String>();
		for(int i=1; i<=dateOfMonth; i++){;
			nameList.add(String.valueOf(i));
		}
		request.setAttribute("nameList", nameList);
		
		Map valueMap = reportDataEngine.getReportData(ReportDataEngine.CUSTOMER_REG_TREND_BY_MONTH, year, month);
		request.setAttribute("valueMap", valueMap);
		if(valueMap.size()>0)
			request.setAttribute("yAxisMaxValue", getYAxisMaxValue(new Integer(Collections.max(valueMap.values()).toString())));
		else
			request.setAttribute("yAxisMaxValue", getYAxisMaxValue(0));
		
		request.setAttribute("numberSuffix", "%C8%CB");//人 GBK
		
			request.setAttribute("hoverTextSuffix", getMessage("report.day"));
		
		return new ModelAndView("report/fusionCharts/Line");
	}
	
	private ModelAndView viewCustomerRegTrendByYear (HttpServletRequest request, HttpServletResponse response){
		locale = request.getLocale();
		request.setAttribute("caption", getMessage("report.yearCustomerReg.trend"));
		request.setAttribute("xAxisName",getMessage("report.date"));
		//request.setAttribute("yAxisName", "销售量\n（笔）");
		
		String year = request.getParameter("year");
		java.util.Calendar calendar =  java.util.Calendar.getInstance();
	    year = year==null?String.valueOf(calendar.get(Calendar.YEAR)):year;
	    
		StringBuilder subcaption = new StringBuilder("(").append(year).append(getMessage("report.date.year")+")");
		request.setAttribute("subcaption", subcaption);
		
		//-------------------start:中英版月份切换--------------------------
		List<String> nameList = new ArrayList<String>();
		for(int i=1; i<=12; i++){;
			nameList.add(String.valueOf(i));
		}
		request.setAttribute("nameList", nameList);
		if(!locale.getLanguage().equals("en")){
			request.setAttribute("nameSuffix", getMessage("report.month"));
		}else{
			request.setAttribute("nameSuffix", null);
		}
		
		//----------------------end:中英版月份切换--------------------------------------
		
		Map valueMap = reportDataEngine.getReportData(ReportDataEngine.CUSTOMER_REG_TREND_BY_YEAR, year);
		request.setAttribute("valueMap", valueMap);
		if(valueMap.size()>0)
			request.setAttribute("yAxisMaxValue", getYAxisMaxValue(new Integer(Collections.max(valueMap.values()).toString())));
		else
			request.setAttribute("yAxisMaxValue", getYAxisMaxValue(0));
		request.setAttribute("numberSuffix", "%C8%CB");//人
		if(locale.getLanguage().equals("en")){
			request.setAttribute("hoverTextSuffix",null);
		}else{
			request.setAttribute("hoverTextSuffix", getMessage("report.month"));
		}
		
		
		return new ModelAndView("report/fusionCharts/Line");
	}
	
	private ModelAndView viewSalesAmountByMonth (HttpServletRequest request, HttpServletResponse response){
		locale = request.getLocale();
		request.setAttribute("caption",  getMessage("report.monthOrderSalesAmount.Statistic"));
		request.setAttribute("xAxisName", getMessage("report.date"));
		//request.setAttribute("yAxisName", "销售额\n（元）");
		
		String year = request.getParameter("year");
		String month = request.getParameter("month");
		String enMonth = null;
		java.util.Calendar calendar =  java.util.Calendar.getInstance();
	    year = year==null?String.valueOf(calendar.get(Calendar.YEAR)):year;
	    month = month==null?String.valueOf(calendar.get(Calendar.MONTH)+1):month;
	    
		calendar.set(Calendar.YEAR, Integer.valueOf(year));
		calendar.set(Calendar.MONTH, Integer.valueOf(month)-1);
		int dateOfMonth = calendar.getActualMaximum(Calendar.DATE);
		//------------------start:英版月份----------------------
	    if(locale.getLanguage().equals("en")){
	    	switch (Integer.valueOf(month)){
	    	case 1:enMonth = "January";break;
	    	case 2:enMonth = "February";break;
	    	case 3:enMonth = "March";break;
	    	case 4:enMonth = "April";break;
	    	case 5:enMonth = "May";break;
	    	case 6:enMonth = "June";break;
	    	case 7:enMonth = "July";break;
	    	case 8:enMonth = "Aguest";break;
	    	case 9:enMonth = "September";break;
	    	case 10:enMonth = "October";break;
	    	case 11:enMonth = "November";break;
	    	case 12:enMonth = "December";break;
	    	default :enMonth ="January" ;break;
	    	}
	    }
		if(locale.getLanguage().equals("en")){
			StringBuilder subcaption = new StringBuilder("(").append(enMonth).append("-").append(year).append(getMessage("report.date.year")+")");
			request.setAttribute("subcaption", subcaption);
		}else{
			StringBuilder subcaption = new StringBuilder("(").append(month).append(getMessage("report.month.to")).append(year).append(getMessage("report.date.year")+")");
			request.setAttribute("subcaption", subcaption);
		}
	
		//------------------end:英版月份----------------------
		List<String> nameList = new ArrayList<String>();
		for(int i=1; i<=dateOfMonth; i++){;
			nameList.add(String.valueOf(i));
		}
		request.setAttribute("nameList", nameList);
		
		Map valueMap = reportDataEngine.getReportData(ReportDataEngine.SALES_AMOUNT_BY_MONTH, year, month);
		request.setAttribute("valueMap", valueMap);
		if(valueMap.size()>0)
			request.setAttribute("yAxisMaxValue", getYAxisMaxValue(new BigDecimal(Collections.max(valueMap.values()).toString())));
		else
			request.setAttribute("yAxisMaxValue", getYAxisMaxValue(BigDecimal.ZERO));
		request.setAttribute("numberSuffix", "%D4%AA");//元
		
			request.setAttribute("hoverTextSuffix", getMessage("report.day"));
		
		return new ModelAndView("report/fusionCharts/Line");
	}
	
	private ModelAndView viewSalesAmountByYear (HttpServletRequest request, HttpServletResponse response){
		locale = request.getLocale();
		request.setAttribute("caption", getMessage("report.yearOrderSalesAmount.Statistic"));
		request.setAttribute("xAxisName", getMessage("report.date"));
		//request.setAttribute("yAxisName", "销售额\n（元）");
		
		String year = request.getParameter("year");
		java.util.Calendar calendar =  java.util.Calendar.getInstance();
	    year = year==null?String.valueOf(calendar.get(Calendar.YEAR)):year;
	    
		StringBuilder subcaption = new StringBuilder("(").append(year).append(getMessage("report.date.year")+")");
		request.setAttribute("subcaption", subcaption);
		//-------------------start:中英版月份切换--------------------------
		List<String> nameList = new ArrayList<String>();
		for(int i=1; i<=12; i++){;
		nameList.add(String.valueOf(i));
		request.setAttribute("nameList", nameList);
		}
		if(!locale.getLanguage().equals("en")){
			request.setAttribute("nameSuffix", getMessage("report.month"));
		}else{
			request.setAttribute("nameSuffix", null);
		}
		
		//----------------------end:中英版月份切换--------------------------------------
		
		
		Map valueMap = reportDataEngine.getReportData(ReportDataEngine.SALES_AMOUNT_BY_YEAR, year);
		request.setAttribute("valueMap", valueMap);
		if(valueMap.size()>0)
			request.setAttribute("yAxisMaxValue", getYAxisMaxValue(new BigDecimal(Collections.max(valueMap.values()).toString())));
		else
			request.setAttribute("yAxisMaxValue", getYAxisMaxValue(BigDecimal.ZERO));
		request.setAttribute("numberSuffix", "%D4%AA");//元
		
		if(locale.getLanguage().equals("en")){
			request.setAttribute("hoverTextSuffix",null);
		}else{
			request.setAttribute("hoverTextSuffix", getMessage("report.month"));
		}
		
		return new ModelAndView("report/fusionCharts/Line");
	}
	
	public ModelAndView viewProductSalesRank (HttpServletRequest request, HttpServletResponse response){
		String topN = request.getParameter("topN");
		String startTime = request.getParameter("startTime");
		String endTime = request.getParameter("endTime");
		//默认为回退1月的前10条
		java.util.Calendar calendar =  java.util.Calendar.getInstance();
		if(topN==null)
			topN = "10";
		if(endTime==null)
			endTime = DateUtil.convertDateToString(calendar.getTime());
		if(startTime==null){
			calendar.add(Calendar.MONTH, -1);
			startTime = DateUtil.convertDateToString(calendar.getTime());
		}
		
		request.setAttribute("topN", topN);
		request.setAttribute("startTime", startTime);
		request.setAttribute("endTime", endTime);
		
		List<Object[]> rankList = reportDataEngine.getProductSalesRankData(new Integer(topN), startTime, endTime+" 23:59:59");
		request.setAttribute("rankList", rankList);
		
		return  new ModelAndView("report/productSalesRank");
	}
	
	public ModelAndView viewCustomerBuyRank (HttpServletRequest request, HttpServletResponse response){
		String topN = request.getParameter("topN");
		String startTime = request.getParameter("startTime");
		String endTime = request.getParameter("endTime");
		//默认为回退1月的前10条
		java.util.Calendar calendar =  java.util.Calendar.getInstance();
		if(topN==null)
			topN = "10";
		if(endTime==null)
			endTime = DateUtil.convertDateToString(calendar.getTime());
		if(startTime==null){
			calendar.add(Calendar.MONTH, -1);
			startTime = DateUtil.convertDateToString(calendar.getTime());
		}
		
		request.setAttribute("topN", topN);
		request.setAttribute("startTime", startTime);
		request.setAttribute("endTime", endTime);
		
		List<Object[]> rankList = reportDataEngine.getCustomerBuyRankData(new Integer(topN), startTime, endTime+" 23:59:59");
		request.setAttribute("rankList", rankList);
		
		return  new ModelAndView("report/customerBuyRank");
	}
	
	public ModelAndView viewSalesIndicator (HttpServletRequest request, HttpServletResponse response){
		String startTime = request.getParameter("startTime");
		String endTime = request.getParameter("endTime");
		request.setAttribute("startTime", startTime);
		request.setAttribute("endTime", endTime);
		
		if(endTime!=null)
			endTime += " 23:59:59";
		
		Map<String,Object[]> indicatorMap =  reportDataEngine.getSalesIndicatorData(startTime, endTime);
		request.setAttribute("indicatorMap", indicatorMap);
		
		return  new ModelAndView("report/salesIndicator");
	}
	
	private ModelAndView viewOrderCountTrendByMonth (HttpServletRequest request, HttpServletResponse response){
		locale = request.getLocale();
		request.setAttribute("caption", getMessage("report.monthOrderCount.trend"));
		request.setAttribute("xAxisName", getMessage("report.date"));
		//request.setAttribute("yAxisName", "销售量\n（笔）");
		
		String year = request.getParameter("year");
		String month = request.getParameter("month");
		String enMonth = null;
		java.util.Calendar calendar =  java.util.Calendar.getInstance();
	    year = year==null?String.valueOf(calendar.get(Calendar.YEAR)):year;
	    month = month==null?String.valueOf(calendar.get(Calendar.MONTH)+1):month;
		calendar.set(Calendar.YEAR, Integer.valueOf(year));
		calendar.set(Calendar.MONTH, Integer.valueOf(month)-1);
		int dateOfMonth = calendar.getActualMaximum(Calendar.DATE);
		//------------------start:英版月份----------------------
	    if(locale.getLanguage().equals("en")){
	    	switch (Integer.valueOf(month)){
	    	case 1:enMonth = "January";break;
	    	case 2:enMonth = "February";break;
	    	case 3:enMonth = "March";break;
	    	case 4:enMonth = "April";break;
	    	case 5:enMonth = "May";break;
	    	case 6:enMonth = "June";break;
	    	case 7:enMonth = "July";break;
	    	case 8:enMonth = "Aguest";break;
	    	case 9:enMonth = "September";break;
	    	case 10:enMonth = "October";break;
	    	case 11:enMonth = "November";break;
	    	case 12:enMonth = "December";break;
	    	default :enMonth ="January" ;break;
	    	}
	    }
		if(locale.getLanguage().equals("en")){
			StringBuilder subcaption = new StringBuilder("(").append(enMonth).append("-").append(year).append(getMessage("report.date.year")+")");
			request.setAttribute("subcaption", subcaption);
		}else{
			StringBuilder subcaption = new StringBuilder("(").append(month).append(getMessage("report.month.to")).append(year).append(getMessage("report.date.year")+")");
			request.setAttribute("subcaption", subcaption);
		}
	
		//------------------end:英版月份----------------------
		
		List<String> nameList = new ArrayList<String>();
		for(int i=1; i<=dateOfMonth; i++){;
			nameList.add(String.valueOf(i));
		}
		request.setAttribute("nameList", nameList);
		
		Map valueMap = reportDataEngine.getReportData(ReportDataEngine.ORDER_COUNT_TREND_BY_MONTH, year, month);
		request.setAttribute("valueMap", valueMap);
		if(valueMap.size()>0)
			request.setAttribute("yAxisMaxValue", getYAxisMaxValue(new Integer(Collections.max(valueMap.values()).toString())));
		else
			request.setAttribute("yAxisMaxValue", getYAxisMaxValue(0));
		
		request.setAttribute("numberSuffix", "%B1%CA");//笔
		
			request.setAttribute("hoverTextSuffix", getMessage("report.day"));
		
		return new ModelAndView("report/fusionCharts/Line");
	}
	
	private ModelAndView viewOrderCountTrendByYear (HttpServletRequest request, HttpServletResponse response){
		locale = request.getLocale();
		request.setAttribute("caption", getMessage("report.yearOrderCount.trend"));
		request.setAttribute("xAxisName", getMessage("report.date"));
		//request.setAttribute("yAxisName", "销售量\n（笔）");
		
		String year = request.getParameter("year");
		java.util.Calendar calendar =  java.util.Calendar.getInstance();
	    year = year==null?String.valueOf(calendar.get(Calendar.YEAR)):year;
	    
		StringBuilder subcaption = new StringBuilder("(").append(year).append(getMessage("report.date.year")+")");
		request.setAttribute("subcaption", subcaption);
		
		//-------------------start:中英版月份切换--------------------------
		List<String> nameList = new ArrayList<String>();
		List<String> enNameList = new ArrayList<String>();
		for(int i=1; i<=12; i++){;
			nameList.add(String.valueOf(i));
		}
		request.setAttribute("nameList", nameList);
		if(!locale.getLanguage().equals("en")){
		request.setAttribute("nameSuffix", getMessage("report.month"));
		}else{
			request.setAttribute("nameSuffix", null);
		}
		
		//----------------------end:中英版月份切换--------------------------------------
		
		Map valueMap = reportDataEngine.getReportData(ReportDataEngine.ORDER_COUNT_TREND_BY_YEAR, year);
		request.setAttribute("valueMap", valueMap);
		if(valueMap.size()>0)
			request.setAttribute("yAxisMaxValue", getYAxisMaxValue(new Integer(Collections.max(valueMap.values()).toString())));
		else
			request.setAttribute("yAxisMaxValue", getYAxisMaxValue(0));
		request.setAttribute("numberSuffix", "%B1%CA");//笔
		
		if(locale.getLanguage().equals("en")){
			request.setAttribute("hoverTextSuffix",null);
		}else{
			request.setAttribute("hoverTextSuffix", getMessage("report.month"));
		}
		
		return new ModelAndView("report/fusionCharts/Line");
	}
	
	/**
	 * 后台主面板-最近订单与客户量趋势
	 */
	public ModelAndView viewOrderAndCustomerTrendRecently(HttpServletRequest request, HttpServletResponse response){
		java.util.Calendar calendar =  java.util.Calendar.getInstance();
		//calendar.add(Calendar.DATE, -20);
		//结束日期，今天
		Date endDate = calendar.getTime();
		String endDateString = DateUtil.convertDateToString(endDate);
		
		//开始日期
		calendar.add(Calendar.DATE, -6);
		Date startDate = calendar.getTime();
		String startDateString = DateUtil.convertDateToString(startDate);
		
		Map<String, Map<String, Long>> trendRecentlyMap = this.reportDataEngine.getOrderAndCustomerTrendRecently(startDate, endDate);
		Map<String, Long> salesOrderTrendRecentlyMap = trendRecentlyMap.get("salesOrder");
		Map<String, Long> customerTrendRecentlyMap = trendRecentlyMap.get("customer");
		
		//封装所有日期对应数据
		List<String> categoryNameList = new ArrayList<String>();
		List<Long> salesOrderTrendRecentlyList = new ArrayList<Long>();
		List<Long> customerTrendRecentlyList = new ArrayList<Long>();
		for(int i=0; i<7; i++){
			int month = calendar.get(Calendar.MONTH)+1;
			int day = calendar.get(Calendar.DATE);
			String categoryName = String.valueOf(month<10?("0"+month):month)+String.valueOf(day<10?("0"+day):day);
			categoryNameList.add(categoryName);
			
			Long value = salesOrderTrendRecentlyMap.get(String.valueOf(day));
			salesOrderTrendRecentlyList.add(value==null?0:value);
			
			Long value2 = customerTrendRecentlyMap.get(String.valueOf(day));
			customerTrendRecentlyList.add(value2==null?0:value2);
			
			calendar.add(Calendar.DATE, 1);
		}
		request.setAttribute("startDate", startDateString);
		request.setAttribute("endDate", endDateString);
		request.setAttribute("categoryNameList", categoryNameList);
		request.setAttribute("salesOrderTrendRecentlyList", salesOrderTrendRecentlyList);
		request.setAttribute("customerTrendRecentlyList", customerTrendRecentlyList);
		
		
		//获取Y轴最大值
		Integer max1 = this.getYAxisMaxValue(0);
		if(!salesOrderTrendRecentlyMap.isEmpty())
			max1 = getYAxisMaxValue(new Integer(Collections.max(salesOrderTrendRecentlyMap.values()).toString()));
		Integer max2 = this.getYAxisMaxValue(0);
		if(!customerTrendRecentlyMap.isEmpty())
			max2 = getYAxisMaxValue(new Integer(Collections.max(customerTrendRecentlyMap.values()).toString()));
		request.setAttribute("yAxisMaxValue", max1>max2?max1:max2);
		
		return new ModelAndView("report/fusionCharts/MSLine");
	}
	
	//基数10
	private Integer getYAxisMaxValue(Integer maxValue){
		double m = 1;
		int count = (int)Math.log10((double)maxValue);
		for (int i = 0; i < count; i++) {  
		    m *= 10;  
		}  
		if(m >= maxValue){
			return (int)m;
		}else if(m*5 >= maxValue){
			return (int)(m*5);
		}else{
			return (int)(m*10);
		}
	}
	
	private BigDecimal getYAxisMaxValue(BigDecimal maxValue){
		double m = 1;
		int count = (int)Math.log10(maxValue.doubleValue());
		for (int i = 0; i < count; i++) {  
		    m *= 10;  
		}  
		if(m >= maxValue.doubleValue()){
			return BigDecimal.valueOf(m);
		}else if(m*5 >= maxValue.doubleValue()){
			return BigDecimal.valueOf(m*5);
		}else{
			return BigDecimal.valueOf(m*10);
		}
	}
}
